package com.google.code.p.paintboard.proportions;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class PaintboardProportion extends JFrame implements ChangeListener,
		ActionListener {

	private File file;
	private BufferedImage img;
	private JLabel lblOriginalX;
	private JLabel lblOriginalY;
	private JLabel lblPreferedX;
	private JLabel lblPreferedY;

	private CustomSpinner<Integer> linesXSpinner;
	private CustomPanel panel;
	private CustomSpinner<Integer> linesYSpinner;

	JFileChooser fc = new JFileChooser();

	double sourceWidth = 20;
	double sourceHeight = 15;

	double preferedWidth = 200;
	double preferedHeight = 150;
	private JLabel lblLeinwandBreitecm;
	private CustomSpinner<Double> boardHeight;
	private CustomSpinner<Double> boardWidth;
	private JPanel imageThreshold;
	private JLabel lblAbbildBreitepixel;
	private CustomSpinner<Integer> canvasWidth;
	private JLabel lblOriginalBreitecm;
	private JLabel lblOriginalHhecm;
	private CustomSpinner<Double> originalWidth;
	private CustomSpinner<Double> originalHeight;
	private JLabel lblEinrckenXpx;
	private JLabel lblEinrckenYpx;
	private CustomSpinner<Integer> shiftX;
	private CustomSpinner<Integer> shiftY;
	private CustomSpinner<Integer> scaleSpinner;
	private boolean noImageRead;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					PaintboardProportion frame = new PaintboardProportion();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public PaintboardProportion() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 1024, 768);

		getContentPane().setLayout(new BorderLayout(0, 0));

		JSplitPane splitPane = new JSplitPane();
		splitPane.setResizeWeight(1.0);
		getContentPane().add(splitPane);

		imageThreshold = new JPanel();
		splitPane.setLeftComponent(imageThreshold);
		imageThreshold.setLayout(null);

		panel = new CustomPanel();
		panel.setBounds(12, 12, 594, 548);
		imageThreshold.add(panel);
		panel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				evalPoint(e.getX(), e.getY());
			}
		});

		JPanel optionsPanel = new JPanel();
		splitPane.setRightComponent(optionsPanel);
		optionsPanel.setLayout(new BoxLayout(optionsPanel, BoxLayout.Y_AXIS));

		JButton btnBildffnen = new JButton("Bild \u00F6ffnen");
		optionsPanel.add(btnBildffnen);

		lblOriginalBreitecm = new JLabel("Original Breite (cm)");
		optionsPanel.add(lblOriginalBreitecm);

		originalWidth = new CustomSpinner<Double>(14.0, 0.0, 1000000.0, 0.1);
		originalWidth.addChangeListener(this);
		optionsPanel.add(originalWidth);

		lblOriginalHhecm = new JLabel("Original H\u00F6he (cm)");
		optionsPanel.add(lblOriginalHhecm);

		originalHeight = new CustomSpinner<Double>(10.0, 0.0, 1000.0, 0.1);
		originalHeight.addChangeListener(this);
		optionsPanel.add(originalHeight);

		lblLeinwandBreitecm = new JLabel("Leinwand Breite (cm)");
		optionsPanel.add(lblLeinwandBreitecm);

		boardWidth = new CustomSpinner<Double>(100.0, 0.0, 1000000.0, 1.0);
		boardWidth.addChangeListener(this);
		optionsPanel.add(boardWidth);

		JLabel lblLeinwandHhecm = new JLabel("Leinwand H\u00F6he (cm)");
		optionsPanel.add(lblLeinwandHhecm);

		boardHeight = new CustomSpinner<Double>(80.0, 0.0, 1000000.0, 1.0);
		boardHeight.addChangeListener(this);
		optionsPanel.add(boardHeight);

		lblEinrckenXpx = new JLabel("Einr\u00FCcken X (px)");
		optionsPanel.add(lblEinrckenXpx);

		shiftX = new CustomSpinner<Integer>();
		shiftX.addChangeListener(this);
		optionsPanel.add(shiftX);

		lblEinrckenYpx = new JLabel("Einr\u00FCcken Y (px)");
		optionsPanel.add(lblEinrckenYpx);

		shiftY = new CustomSpinner<Integer>();
		shiftY.addChangeListener(this);
		optionsPanel.add(shiftY);

		lblAbbildBreitepixel = new JLabel("Abbild Breite (pixel)");
		optionsPanel.add(lblAbbildBreitepixel);

		canvasWidth = new CustomSpinner<Integer>(700, 1, 2000, 5);
		canvasWidth.addChangeListener(this);
		optionsPanel.add(canvasWidth);

		JLabel lblSkalierenpixel = new JLabel("Skalieren (pixel)");
		optionsPanel.add(lblSkalierenpixel);

		scaleSpinner = new CustomSpinner<Integer>(0, Integer.MIN_VALUE,
				Integer.MAX_VALUE, 1);
		scaleSpinner.addChangeListener(this);
		optionsPanel.add(scaleSpinner);

		JLabel lblLinienX = new JLabel("Linien X");
		optionsPanel.add(lblLinienX);

		linesXSpinner = new CustomSpinner<Integer>();
		optionsPanel.add(linesXSpinner);

		JLabel lblLinienY = new JLabel("Linien Y");
		optionsPanel.add(lblLinienY);

		linesYSpinner = new CustomSpinner<Integer>();
		optionsPanel.add(linesYSpinner);
		linesYSpinner.addChangeListener(this);

		lblPreferedX = new JLabel("Prefered X");
		optionsPanel.add(lblPreferedX);

		lblPreferedY = new JLabel("Prefered Y");
		optionsPanel.add(lblPreferedY);

		lblOriginalX = new JLabel("Original X");
		optionsPanel.add(lblOriginalX);

		lblOriginalY = new JLabel("Original Y");
		optionsPanel.add(lblOriginalY);

		noImageRead = true;
		readImage();
		panel.setBorder(new LineBorder(new Color(0, 0, 0)));
		linesXSpinner.addChangeListener(this);
		btnBildffnen.addActionListener(this);

		stateChanged(null);
	}

	private void readImage() {
		try {
			// TODO just a quickfix
			if (noImageRead) {
				img = ImageIO.read(PaintboardProportion.class
						.getResource("bild.jpg"));
				noImageRead = false;
			}
			else img = ImageIO.read(file);
			panel.setImg(img);
			int scaleValue = (img.getWidth() < panel.getWidth()) ? panel
					.getWidth() - img.getWidth() : -(img.getWidth() - panel
					.getWidth());
			scaleSpinner.setValue(scaleValue);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	protected void evalPoint(int clickX, int clickY) {
		System.out.println("clicked " + clickX + "/" + clickY);

		double preferedX = clickX * boardWidth.getDouble() / panel.getWidth();
		double preferedY = clickY * boardHeight.getDouble() / panel.getHeight();

		double originalX = clickX * originalWidth.getDouble()
				/ panel.getWidth();
		double originalY = clickY * originalHeight.getDouble()
				/ panel.getHeight();

		lblOriginalX.setText("Original X: " + originalX);
		lblOriginalY.setText("Original Y: " + originalY);
		lblPreferedX.setText("Prefered X: " + preferedX);
		lblPreferedY.setText("Prefered Y: " + preferedY);

		System.out.println("prefered:" + preferedX + "/" + preferedY);
	}

	@Override
	public void stateChanged(ChangeEvent arg0) {
		panel.setOriginalSize(originalWidth.getDouble(),
				originalHeight.getDouble());
		panel.setBoardSize(boardWidth.getDouble(), boardHeight.getDouble());
		panel.setWidth(canvasWidth.getInteger());
		panel.setScale(scaleSpinner.getInteger());
		panel.setShamt(shiftX.getInteger(), shiftY.getInteger());
		panel.setLinesX(linesXSpinner.getInteger() + 1);
		panel.setLinesY(linesYSpinner.getInteger() + 1);
		panel.repaint();
	}

	@Override
	public void actionPerformed(ActionEvent e) {

		int returnVal = fc.showOpenDialog(this);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			file = fc.getSelectedFile();
			readImage();
			panel.repaint();

			System.out.println("Opening: " + file.getName() + ".");
		} else {
			System.out.println("Open command canceled by user.");
		}
	}
}
